package org.fox.beetl.ext.spring;

import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.beetl.core.Configuration;
import org.beetl.core.ErrorHandler;
import org.beetl.core.Format;
import org.beetl.core.Function;
import org.beetl.core.GroupTemplate;
import org.beetl.core.ResourceLoader;
import org.beetl.core.TagFactory;
import org.beetl.core.VirtualAttributeEval;
import org.beetl.core.VirtualClassAttribute;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.Resource;

/**
 * GroupTemplate工厂Bean<br>
 * 这个类不一定在Spring Web环境中使用，一般的Spring应用程序也能使用
 * 
 * @author Chen Rui
 */
public class GroupTemplateFactoryBean implements FactoryBean<GroupTemplate> {
	/* ----- ----- ----- ----- 属性 ----- ----- ----- ----- */
	/**
	 * 配置属性
	 */
	private Properties configProperties = null;
	/**
	 * 配置文件地址
	 */
	private Resource configFileResource = null;
	/**
	 * Beetl资源加载器，如果未指定，会自动依据ApplicationContext和配置文件识别
	 */
	private ResourceLoader resourceLoader = null;
	/**
	 * 异常处理器
	 */
	private ErrorHandler errorHandler = null;
	/**
	 * 共享变量
	 */
	private Map<String, Object> sharedVars = null;
	/**
	 * 自定义函数
	 */
	private Map<String, Function> functions = null;
	/**
	 * 自定义类型默认格式化器
	 */
	private Map<Class<?>, Format> typeFormats = null;
	/**
	 * 自定义格式化器
	 */
	private Map<String, Format> formats = null;
	/**
	 * 自定义标签
	 */
	private Map<String, TagFactory> tagFactorys = null;
	/**
	 * 自定义函数包
	 */
	private Map<String, Object> functionPackages = null;
	/**
	 * 自定义虚拟属性
	 */
	private Map<Class<?>, VirtualClassAttribute> virtualClassAttributes = null;
	/**
	 * 自定义虚拟属性执行器
	 */
	private List<VirtualAttributeEval> virtualAttributeEvals = null;

	/**
	 * 配置属性
	 * 
	 * @param configProperties
	 */
	public void setConfigProperties(Properties configProperties) {
		this.configProperties = configProperties;
	}

	/**
	 * 配置文件地址
	 * 
	 * @param configFileResource
	 */
	public void setConfigFileResource(Resource configFileResource) {
		this.configFileResource = configFileResource;
	}

	/**
	 * Beetl资源加载器，如果未指定，会自动依据ApplicationContext和配置文件识别
	 * 
	 * @param resourceLoader
	 */
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	/**
	 * 共享参数
	 * 
	 * @param sharedVars
	 */
	public void setSharedVars(Map<String, Object> sharedVars) {
		this.sharedVars = sharedVars;
	}

	/**
	 * 自定义函数
	 * 
	 * @param functions
	 */
	public void setFunctions(Map<String, Function> functions) {
		this.functions = functions;
	}

	/**
	 * 自定义类型默认格式化器
	 * 
	 * @param typeFormats
	 */
	public void setTypeFormats(Map<Class<?>, Format> typeFormats) {
		this.typeFormats = typeFormats;
	}

	/**
	 * 自定义格式化器
	 * 
	 * @param formats
	 */
	public void setFormats(Map<String, Format> formats) {
		this.formats = formats;
	}

	/**
	 * 自定义标签
	 * 
	 * @param tagFactorys
	 */
	public void setTagFactorys(Map<String, TagFactory> tagFactorys) {
		this.tagFactorys = tagFactorys;
	}

	/**
	 * 异常处理器
	 * 
	 * @param errorHandler
	 */
	public void setErrorHandler(ErrorHandler errorHandler) {
		this.errorHandler = errorHandler;
	}

	/**
	 * 自定义函数包
	 * 
	 * @param functionPackages
	 */
	public void setFunctionPackages(Map<String, Object> functionPackages) {
		this.functionPackages = functionPackages;
	}

	/**
	 * 自定义虚拟属性
	 * 
	 * @param virtualClassAttributes
	 */
	public void setVirtualClassAttributes(Map<Class<?>, VirtualClassAttribute> virtualClassAttributes) {
		this.virtualClassAttributes = virtualClassAttributes;
	}

	/**
	 * 自定义虚拟属性执行器
	 * 
	 * @param virtualAttributeEvals
	 */
	public void setVirtualAttributeEvals(List<VirtualAttributeEval> virtualAttributeEvals) {
		this.virtualAttributeEvals = virtualAttributeEvals;
	}

	/* ----- ----- ----- ----- 其他方法 ----- ----- ----- ----- */
	/**
	 * 创建GroupTemplate对象
	 * 
	 * @return
	 * @throws IOException
	 *             配置文件数据加载IO异常
	 * @throws Exception
	 */
	@Override
	public GroupTemplate getObject() throws IOException, Exception {
		// 配置数据加载
		Configuration configuration = null;
		// 如果都未设置，取默认的配置
		if ((configProperties == null) && (configFileResource == null)) {
			configuration = Configuration.defaultConfiguration();
		} else { // 否则采用Properties的形式加载
			Properties properties = new Properties();
			// 如果指定了配置文件，先加载配置文件
			if (configFileResource != null) {
				properties.load(configFileResource.getInputStream());
			}
			// 如果指定了configProperties，对已加载的内容进行替换
			if (configProperties != null) {
				for (Enumeration<?> keys = configProperties.propertyNames(); keys.hasMoreElements();) {
					String key = (String) keys.nextElement();
					String value = configProperties.getProperty(key);
					properties.setProperty(key, value);
				}
			}
			// 使用配置项配置properties
			configuration = new Configuration(properties);
		}

		// 创建GroupTemplate
		GroupTemplate groupTemplate = null;
		// 如果未指定，返回
		if (resourceLoader != null) {
			groupTemplate = new GroupTemplate(resourceLoader, configuration);
		} else {
			groupTemplate = new GroupTemplate(configuration);
		}

		// GroupTemplate 配置
		// 设置异常处理器
		if (errorHandler != null) {
			groupTemplate.setErrorHandler(errorHandler);
		}

		// 设置共享变量
		if (sharedVars != null) {
			groupTemplate.setSharedVars(sharedVars);
		}
		// 注册自定义函数
		if ((functions != null) && (functions.size() != 0)) {
			for (Entry<String, Function> entry : functions.entrySet()) {
				groupTemplate.registerFunction(entry.getKey(), entry.getValue());
			}
		}

		// 注册自定义类型默认格式化器
		if ((typeFormats != null) && (typeFormats.size() != 0)) {
			for (Entry<Class<?>, Format> entry : typeFormats.entrySet()) {
				groupTemplate.registerDefaultFormat(entry.getKey(), entry.getValue());
			}
		}
		// 注册自定义格式化器
		if ((formats != null) && (formats.size() != 0)) {
			for (Entry<String, Format> entry : formats.entrySet()) {
				groupTemplate.registerFormat(entry.getKey(), entry.getValue());
			}
		}

		// 注册自定义标签
		if ((tagFactorys != null) && (tagFactorys.size() != 0)) {
			for (Entry<String, TagFactory> entry : tagFactorys.entrySet()) {
				groupTemplate.registerTagFactory(entry.getKey(), entry.getValue());
			}
		}

		// 注册自定义函数包
		if ((functionPackages != null) && (functionPackages.size() != 0)) {
			for (Entry<String, Object> entry : functionPackages.entrySet()) {
				groupTemplate.registerFunctionPackage(entry.getKey(), entry.getValue());
			}
		}

		// 自定义虚拟属性
		if ((virtualClassAttributes != null) && (virtualClassAttributes.size() != 0)) {
			for (Entry<Class<?>, VirtualClassAttribute> entry : virtualClassAttributes.entrySet()) {
				groupTemplate.registerVirtualAttributeClass(entry.getKey(), entry.getValue());
			}
		}

		// 自定义虚拟属性执行器
		if ((virtualAttributeEvals != null) && (virtualAttributeEvals.size() != 0)) {
			for (VirtualAttributeEval virtualAttributeEval : virtualAttributeEvals) {
				groupTemplate.registerVirtualAttributeEval(virtualAttributeEval);
			}
		}

		return groupTemplate;
	}

	@Override
	public Class<?> getObjectType() {
		return GroupTemplate.class;
	}

	/**
	 * 生成的GroupTemplate在Spring单例管理
	 * 
	 * @return
	 */
	@Override
	public boolean isSingleton() {
		return true;
	}
}
